home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 001-025 / scopedisk4 / macfont / unpack.c < prev   
C/C++ Source or Header  |  1995-03-18  |  5KB  |  201 lines

  1. /*
  2.  * Macintosh font suitcase unpacker by John O'Neill
  3.  *
  4.  * Amiga modifications by Rico Mariani
  5.  *
  6.  * The -x flag is used to skip the 128 info section that is placed
  7.  * at the head of the file when the suitcase is uploaded from
  8.  * the Mac by some versions of xmodem.
  9.  *
  10.  * (C)1987 John O'Neill & Rico Mariani
  11.  *
  12.  */
  13.  
  14. #include <exec/types.h>
  15. #include "extract.h"
  16. #include <stdio.h>
  17.  
  18. void *malloc();
  19. void *PtoC();
  20. int debug = 1;
  21.  
  22. main(argc,argv)
  23. int argc;
  24. char **argv;
  25. {
  26.     unsigned char *res, rheader[16];
  27.     int i, j, c;
  28.     int Data_loc, Map_loc, Data_length, Map_length, Res_length;
  29.     int Type_List_loc, Name_List_loc;
  30.     int Num_Res_Types, Type_loc, Num_Fonts, Ref_List_loc;
  31.     int Ref_loc, Res_ID, temp, Res_Name_loc, Res_Attributes;
  32.     int Res_Data_loc;
  33.     int Font_ID, Point_Size, Font_Num, Font_Size;
  34.     unsigned char **Font_Name;
  35.     unsigned char File_Name[32];
  36.     FILE *f,*fontfile;
  37.     int skip = 0;
  38.  
  39.     /* Start up */
  40.  
  41.     if (argc < 2 || argc > 4) {
  42.         fprintf(stderr,"Usage: %s [-x] FontFile\n",argv[0]);
  43.         exit(1);
  44.     }
  45.  
  46.     if (!strcmp(argv[1],"-x"))
  47.         skip = 1;
  48.  
  49.     f = fopen(argv[1+skip],"r");
  50.     if (!f) {
  51.         fprintf(stderr,"%s: Cannot open %s\n",argv[0],argv[1+skip]);
  52.         exit(1);
  53.     }
  54.  
  55.     /* Skip .info file sent by XMODEM */
  56.  
  57.     if (skip) for(i = 0; i < 128; i++) fgetc(f);
  58.  
  59.     /* Get resource file header */
  60.  
  61.     fread( rheader, sizeof(rheader), 1, f);
  62.  
  63.     Data_loc    = X_LONG(rheader + 0);
  64.     Map_loc        = X_LONG(rheader + 4);
  65.     Data_length = X_LONG(rheader + 8);
  66.     Map_length  = X_LONG(rheader + 12);
  67.     Res_length  = Data_length + Map_length + 256;
  68.  
  69.     /* allocate memory for the rest of the resource */
  70.     res = malloc(Res_length);
  71.  
  72.     /* read in everything but the header */
  73.     fread( res+16, Res_length-16, 1, f );
  74.     fclose(f);
  75.  
  76.     /* Look for FONT resources in the resource map */
  77.  
  78.     Type_List_loc = Map_loc + X_UWORD(res + Map_loc + 24);
  79.     Name_List_loc = Map_loc + X_UWORD(res + Map_loc + 26);
  80.  
  81.     Num_Res_Types = 1 + X_UWORD(res + Type_List_loc);
  82.  
  83.     printf("There are %d Res Types in the file\n", Num_Res_Types);
  84.  
  85.     for(i = 0; i < Num_Res_Types; i++) {
  86.         Type_loc = Type_List_loc + i*10 + 2;
  87.         if (X_ULONG(res + Type_loc) == 'FONT') {
  88.             Num_Fonts = 1 + X_UWORD(res+Type_loc+4);
  89.             Ref_List_loc = Type_List_loc +
  90.                 X_UWORD(res + Type_loc + 6);
  91.             printf("Found FONT rsrc with %d fonts\n", Num_Fonts);
  92.  
  93.         }
  94.     }
  95.  
  96.     /* Get the FONT names first: this is the name of the Resources
  97.        which have ResId a multiple of 128 */
  98.  
  99.     Font_Num = 1;
  100.     /* need one pointer for each possible font id */
  101.     Font_Name = malloc(sizeof(char *) * 256);
  102.     if (!Font_Name) {
  103.         printf("Error, no memory for font name pointer array\n");
  104.         exit(-1);
  105.     }
  106.  
  107.     for(i = 0; i < Num_Fonts; i++) {
  108.         Ref_loc    = Ref_List_loc + 12*i;
  109.         Res_ID     = X_UWORD(res + Ref_loc);
  110.         Font_ID    = Res_ID >> 7;
  111.         Point_Size = Res_ID & 0x7f;
  112.  
  113.         if (Point_Size == 0) {
  114.             temp = X_UWORD(res + Ref_loc + 2);
  115.  
  116.             if (temp == 0xffff) {
  117.                 Font_Name[Font_ID] = malloc(10);
  118.                 if (!Font_Name[Font_ID]) {
  119.                     printf("Error, no memory for name\n");
  120.                     exit(-1);
  121.                 }
  122.  
  123.                 sprintf(Font_Name[Font_ID],"FONT%d",
  124.                     Font_Num );
  125.  
  126.                 Font_Num++;
  127.             }
  128.             else {
  129.                 Res_Name_loc = Name_List_loc + temp;
  130.                 Font_Name[Font_ID] = PtoC(res+Res_Name_loc);
  131.             }
  132.         }
  133.     }
  134.  
  135.     /* Get the info on each of the FONT resources found */
  136.  
  137.     for(i = 0; i < Num_Fonts; i++) {
  138.         Ref_loc = Ref_List_loc + 12*i;
  139.         Res_ID  = X_UWORD(res + Ref_loc );
  140.         Font_ID = Res_ID >> 7;
  141.         Point_Size = Res_ID & 0x7f;
  142.  
  143.         temp            = X_UWORD(res + Ref_loc + 2);
  144.         Res_Name_loc   = (temp == 0xffff) ? -1 : Name_List_loc+temp;
  145.         Res_Attributes = res[Ref_loc + 4];
  146.         Res_Data_loc   = Data_loc + X_UTRIP(res + Ref_loc + 5);
  147.         Font_Size      = X_ULONG( res + Res_Data_loc );
  148.  
  149.         if (Point_Size != 0) {
  150.             for(j = 0;; j++) {
  151.                 c = Font_Name[Font_ID][j];
  152.                 if (c == ' ') c = '_';
  153.                 if (c != 0)
  154.                     File_Name[j] = c;
  155.                 else
  156.                     break;
  157.             }
  158.  
  159.             File_Name[j] = '.';
  160.             j++;
  161.             sprintf(&File_Name[j],"%d",Point_Size);
  162.  
  163.             printf("Font:%s %d -> File:%s  (Size = %d)\n",
  164.                 Font_Name[Font_ID],Point_Size,File_Name,
  165.                 Font_Size);
  166.  
  167.             fontfile = fopen(File_Name,"w");
  168.             if (!fontfile) {
  169.                 fprintf(stderr,"%s: Cannot open %s\n",
  170.                     argv[0],File_Name);
  171.                 exit(1);
  172.             }
  173.  
  174.             fwrite( res+Res_Data_loc+4, Font_Size, 1, fontfile);
  175.             fclose(fontfile);
  176.         }
  177.     }
  178. }
  179.  
  180. void *PtoC(s1)
  181. register unsigned char *s1;
  182. {
  183.     register unsigned char *s2;
  184.     register int i;
  185.     int len;
  186.     unsigned char *s;
  187.  
  188.     len = *s1++;
  189.  
  190.     s = s2 = malloc(len + 1);
  191.     if (!s2) {
  192.         printf("Error, not enough memory to make C string\n");
  193.         exit(-1);
  194.     }
  195.  
  196.     for (i= len; --i>=0; ) *s2++ = *s1++;
  197.  
  198.     *s2 = 0;
  199.     return(s);
  200. }
  201.